﻿using HZ.Public;
using HZ.PublicDispatch.PalletSrv;
using Microsoft.SqlServer.Server;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;
using System.Xml.Linq;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using Newtonsoft.Json;
using System.Web.Script.Serialization;
using System.IO;
using System.Data;
using System.Windows.Input;
using MySql.Data.MySqlClient;

namespace HZ.PublicDispatch
{
    public class DispatchClass
    {
        private static bool bInitPutTakePalletLoop = false;

        private static int nThreadNUM = 0;

        public static int FCDoorOpenedInPlace = 603;

        public static int Smoke1Index = 600;

        public static int Smoke2Index = 601;

        public static int COSmokeIndex = 602;

        public static string RLCS = ConfigurationManager.AppSettings["容量测试"];

        public static string RLCSFC = ConfigurationManager.AppSettings["容量测试复测"];

        public static string DGCS = ConfigurationManager.AppSettings["DG测试"];

        public static string JRLFC = ConfigurationManager.AppSettings["简容量复测"];

        public static string 工厂 = ConfigurationManager.AppSettings["工厂"];
        public static string 生产线 = ConfigurationManager.AppSettings["生产线"];
        public static string 工序_化成 = ConfigurationManager.AppSettings["工序_化成"];
        public static string 工序_分容 = ConfigurationManager.AppSettings["工序_分容"];
        public static string 工序_补电 = ConfigurationManager.AppSettings["工序_补电"];
        public static string 工序_复测 = ConfigurationManager.AppSettings["工序_复测"];
        public static string 工序_简容量复测 = ConfigurationManager.AppSettings["工序_简容量复测"];
        public static string 工序_DCIR = ConfigurationManager.AppSettings["工序_DCIR"];
        public static string 资源编号 = ConfigurationManager.AppSettings["资源编号"];
        public static string 设备编号_化成 = ConfigurationManager.AppSettings["设备编号_化成"];
        public static string 设备编号_分容 = ConfigurationManager.AppSettings["设备编号_分容"];
        public static string 设备编号_DCIR  = ConfigurationManager.AppSettings["设备编号_DCIR"];
        public static string 所在位置 = ConfigurationManager.AppSettings["所在位置"];
        public static string url10001 = ConfigurationManager.AppSettings["MSG10001"];
        public static string url10002 = ConfigurationManager.AppSettings["MSG10002"];
        public static string url10003 = ConfigurationManager.AppSettings["MSG10003"];

        /*        /// <summary>
                /// 放取盘线程测试
                /// </summary>
                public static void PutTakePalletLoop()
                {
                    if (!bInitPutTakePalletLoop)
                    {
                        bInitPutTakePalletLoop = true;

                        Dictionary<int, bool> dic = new Dictionary<int, bool>();

                        new Thread(() =>
                        {
                            ServiceReference1.WebService1SoapClient TestClient = new ServiceReference1.WebService1SoapClient();

                            if (TestClient != null)
                            {
                                PublicClass.WriteLog2DB("开启放/取盘线程", PublicClass.LogContentType.Dispatcher);
                                while (true)
                                {
                                    if (PublicClass.bQuit)
                                        break;
                                    ServiceReference1.FormListDataRsp wdatas = TestClient.GetListFormByAll();
                                    if (wdatas != null)
                                    {
                                        PublicClass.bMESComm.bTemp = true;
                                        foreach (ServiceReference1.FormFloor data in wdatas.data)
                                        {
                                            if (!dic.ContainsKey(data.id) || !dic[data.id])
                                            {
                                                dic[data.id] = true;
                                                nThreadNUM++;
                                                ThreadPool.QueueUserWorkItem(x =>
                                                {
                                                    DeviceClass device = GetDeviceByID(data.id);
                                                    if (device != null)
                                                    {
                                                        device.PalletNo = data.tray_code;
                                                        PutPallet(device, data);
                                                        //TakePallet(device, data);
                                                    }
                                                    nThreadNUM--;

                                                    dic[data.id] = false;
                                                });
                                            }

                                        }
                                    }
                                    else
                                    {
                                        PublicClass.bMESComm.strTemp = "无法获取库位信息";
                                        PublicClass.bMESComm.bTemp = false;
                                        Thread.Sleep(5000);
                                    }
                                    Thread.Sleep(3000);
                                }
                            }
                            else
                            {
                                PublicClass.bMESComm.strTemp = "接口初始化失败";
                                PublicClass.bMESComm.bTemp = false;
                                PublicClass.WriteLog2DB("开启放/取盘线程初始化失败", PublicClass.LogContentType.Dispatcher);
                            }
                        }).Start();
                    }
                }

                /// <summary>
                /// 放盘测试
                /// </summary>
                public static void PutPallet(DeviceClass device, ServiceReference1.FormFloor data)
                {
                    ServiceReference1.WebService1SoapClient TestClient = new ServiceReference1.WebService1SoapClient();
                    try
                    {
                        if (device != null)
                        {
                            //if (device.NeedPutPallet())
                            {
                                if (data.floor_status == 0)
                                {
                                    TestClient.UpdateFloorStatus(data.id, 2);
                                }
                            }

                            if (data.get_put_req == 2)
                            {
                                //if (device.NeedPutPallet())
                                {
                                    TestClient.UpdateGetPutAns(data.id, 2);
                                }
                            }

                            if (data.get_put_req == 22)
                            {
                                ServiceReference1.MsgRsp rsp = TestClient.UpdateFloorStatus(data.id, 3);
                                device.PalletNo = data.tray_code;
                                if (rsp != null && rsp.result)
                                {
                                    PublicClass.WriteLog2DB(device.DeviceNo + "放盘完毕", PublicClass.LogContentType.Dispatcher);
                                }
                            }
                        }
                    }
                    catch (Exception ee)
                    {
                        PublicClass.WriteLog("PutTakeClass.PutPallet：" + ee.Message);
                    }
                }

                /// <summary>
                /// 取盘测试
                /// </summary>
                public static bool TakePallet(DeviceClass device, int id)
                {
                    ServiceReference1.WebService1SoapClient TestClient = new ServiceReference1.WebService1SoapClient();
                    ServiceReference1.FormDataRsp data = TestClient.GetListFormByID(id);
                    if (data != null)
                    {
                        try
                        {
                            if (device != null)
                            {
                                if (device.NeedTakePallet())
                                {
                                    if (data.data.floor_status == 3)
                                    {
                                        TestClient.UpdateFloorStatus(data.data.id, 1);
                                    }
                                }

                                if (data.data.get_put_req == 1)
                                {

                                    if (device.NeedTakePallet())
                                    {
                                        TestClient.UpdateGetPutAns(data.data.id, 1);
                                    }
                                }

                                if (data.data.get_put_req == 21)
                                {
                                    ServiceReference1.MsgRsp rsp = TestClient.UpdateFloorStatus(data.data.id, 0);
                                    if (rsp != null && rsp.result)
                                    {
                                        MsgPumpClass.PublishMsg("TakePalletComplete", device);
                                        PublicClass.WriteLog2DB(device.DeviceNo + "取盘完毕", PublicClass.LogContentType.Dispatcher);
                                        return true;
                                    }
                                }

                            }
                        }
                        catch (Exception ee)
                        {
                            PublicClass.WriteLog("PutTakeClass.TakePallet：" + ee.Message);
                        }
                    }
                    return false;
                }

                /// <summary>
                /// 获取电池-测试数据
                /// </summary>
                /// <param name="strPalletNo"></param>
                /// <returns></returns>
                public static Dictionary<int, string> GetBatteryNo(DeviceClass device)
                {
                    Dictionary<int, string> dic = new Dictionary<int, string>();
                    dic.Add(0, "batt0415114523");
                    dic.Add(1, "batt0415051909");
                    dic.Add(2, "batt0415052003");
                    dic.Add(3, "batt0415113417");
                    dic.Add(4, "batt0415113453");
                    dic.Add(5, "batt0415113529");
                    dic.Add(6, "batt0415113603");
                    dic.Add(7, "batt0415113637");
                    dic.Add(8, "batt0415113738");
                    dic.Add(9, "batt0415113813");
                    dic.Add(10, "batt0415113849");
                    dic.Add(11, "batt0415113924");
                    dic.Add(12, "batt0415114001");
                    dic.Add(13, "batt0415114036");
                    dic.Add(14, "batt0415114102");
                    dic.Add(15, "batt0415114128");
                    dic.Add(16, "batt0415114153");
                    dic.Add(17, "batt0415114221");
                    dic.Add(18, "batt0415114247");
                    dic.Add(19, "batt0415114313");
                    dic.Add(20, "batt0415114339");
                    dic.Add(21, "batt0415114405");
                    dic.Add(22, "batt0415114432");
                    dic.Add(23, "batt0415114458");
                    return dic;
                }*/

        /*        /// <summary>
                /// 获取托盘类型-测试数据
                /// </summary>
                /// <param name="strPalletNo"></param>
                /// <returns></returns>
                public static int GetPalletType(string strPalletNo)
                {
                    if (strPalletNo == "DCIR")
                    {
                        return 1;//校准工装&计量工装&DCIR工装
                    }
                    else
                    {
                        return 0;
                    }
                }*/

        /// <summary>
        /// 开启放/取盘线程
        /// </summary>
        public static void PutTakePalletLoop()
        {
            if (!bInitPutTakePalletLoop)
            {
                bInitPutTakePalletLoop = true;

                Dictionary<int, bool> dic = new Dictionary<int, bool>();//当前正在进行取放盘操作的设备记录

                new Thread(() =>
                {
                    bool b1 = CallWCSClass.InitPalletSrv();
                    bool b2 = CallWCSClass.InitWarehouseSrv();

                    if (b1 && b2)
                    {
                        PublicClass.WriteLog2DB("开启放/取盘线程", PublicClass.LogContentType.Dispatcher);
                        while (true)
                        {
                            if (PublicClass.bQuit)
                                break;
                            WarehouseSrv.FormListDataRsp wdatas = CallWCSClass.GetListFormByAll();//获取所有库位在调度系统中的状态，执行InitPalletSrv()后，设置中为化成sNames=Form，为分容sNames=AG
                            if (wdatas != null)
                            {
                                PublicClass.bMESComm.bTemp = true;
                                foreach (WarehouseSrv.FormFloor data in wdatas.data)
                                {
                                    if (!dic.ContainsKey(data.id) || !dic[data.id])
                                    {
                                        CallWCSClass.UpdateSysLive(data.id.ToString());
                                        #region 取放盘

                                        dic[data.id] = true;
                                        nThreadNUM++;
                                        ThreadPool.QueueUserWorkItem(x =>
                                        {
                                            DeviceClass device = GetDeviceByID(data.id);
                                            if (device != null && device.DeviceManual == true)//device.DeviceManual == true时表示为手动，不进行自动调度
                                            {
                                                CallWCSClass.UpdateFloorStatus(data.id, 0);//手动模式的库位改变库位状态为初始

                                            }
                                            if (device != null && device.DeviceManual != true)
                                            {
                                                device.PalletNo = data.tray_code;//在放盘前通过接口获得托盘编号，会导致有盘后库位状态没切换到工作中时就开始测试
                                                if (data.load_status == 70) { device.PalletNo = "CLJD"; }
                                                else if (data.load_status == 71) { device.PalletNo = "WD"; }
                                                else if (data.load_status == 73) { device.PalletNo = "FY"; }
                                                else if (data.load_status == 75) { device.PalletNo = "CXZ"; }
                                                else if (data.load_status == 76) { device.PalletNo = "BXZ"; }
                                                else if (data.load_status == 78) { device.PalletNo = "BLJD"; }
                                                else if (data.load_status == 79) { device.PalletNo = "XX"; }
                                                UpdateInfoToWCS(device, data);
                                                PutPallet(device, data);
                                                //TakePallet(device, data);//改为单独调用取盘方法
                                            }
                                            nThreadNUM--;

                                            dic[data.id] = false;
                                        });

                                        #endregion
                                    }

                                }
                            }
                            else
                            {
                                PublicClass.bMESComm.strTemp = "无法获取库位信息";
                                PublicClass.bMESComm.bTemp = false;
                                Thread.Sleep(5000);
                            }

                            //CallWCSClass.UpdateSysLive(PublicClass.projectConfig.system.strCCNo);//上位机心跳，用DMS服务器的IP作为客户端软件名称
                            Thread.Sleep(3000);
                        }
                    }
                    else
                    {
                        PublicClass.bMESComm.strTemp = "接口初始化失败";
                        PublicClass.bMESComm.bTemp = false;
                        PublicClass.WriteLog2DB("开启放/取盘线程初始化失败", PublicClass.LogContentType.Dispatcher);
                    }
                }).Start();
            }

        }

        /// <summary>
        /// 放盘
        /// </summary>
        /// <param name="device"></param>
        /// <param name="data"></param>
        private static void PutPallet(DeviceClass device, WarehouseSrv.FormFloor data)
        {
            try
            {
                if (device != null)
                {
                    //只要有一个通道处于非离线且非禁用，视为DCDC非全部离线
                    int a = 0;
                    foreach (ChannelClass channel in device.ChannelList)
                    {
                        if (channel.ChannelState.StateNo != 101 && channel.ChannelState.StateNo != 107)
                        {
                            a = 1;
                        }
                    }
                    if (a == 0 && data.floor_status != 0)
                    {
                        CallWCSClass.UpdateFloorStatus(data.id, 0);//如果DCDC全部离线，则修改库位状态为初始0
                    }
                    if (device.NeedPutPallet() && a == 1)//设备就绪，且没有托盘，可以放盘了
                    {
                        if (data.floor_status == 0)
                        {
                            CallWCSClass.UpdateFloorStatus(data.id, 2);//更新对应id库位状态信息 0未知，1可取，2可放，3工作中
                        }
                    }

                    if (data.get_put_req == 2)
                    {
                        if (device.NeedPutPallet())//再次判断是否允许放盘
                        {
                            CallWCSClass.UpdateGetPutAns(data.id, 2);//2放盘，1取盘
                        }
                    }

                    if (data.start_mac == 1 && data.floor_status == 5)//已经放好托盘了 去掉判断条件 && data.get_put_req == 22
                    {
                        if (data.load_status == 50 || data.load_status == 60 || data.load_status == 61)
                        {
                            string sOperation = "";
                            if (data.load_status == 50)
                            {
                                sOperation = "FORMN";
                            }
                            else if (data.load_status == 60)
                            {
                                sOperation = "CAPAC1";
                            }
                            else if (data.load_status == 61)
                            {
                                sOperation = "CAPAC6";
                            }
                            device.PalletNo = data.tray_code;//当库位状态为5时，即开始测试状态，此时获得托盘条码                                                      
                            MsgRsp startdata = CallWCSClass.SetFormAGDGTestStart(sOperation, data.tray_code, data.id.ToString(), data.id.ToString(), DateTime.Now);//调用开始测试
                            WarehouseSrv.MsgRsp rsp = CallWCSClass.UpdateFloorStatus(data.id, 3);//更新对应id库位状态信息 0未知，1可取，2可放，3工作中  
                            if (rsp != null && rsp.result)
                            {
                                CallWCSClass.UpdateStartMac(data.id, 0);//0初始，1启动请求
                                PublicClass.WriteLog2DB(device.DeviceNo + "放盘完毕", PublicClass.LogContentType.Dispatcher);
                            }
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                PublicClass.WriteLog("PutTakeClass.PutPallet：" + ee.Message);
            }
        }

        /// <summary>
        /// 取盘
        /// </summary>
        /// <param name="device"></param>
        /// <param name="id"></param>
        public static bool TakePallet(DeviceClass device, int id)
        {
            WarehouseSrv.FormDataRsp data = CallWCSClass.GetListFormByID(id);
            if (data != null)
            {
                try
                {
                    if (device != null)
                    {
                        if (device.NeedTakePallet() && device.dilist[PT.YH_DIIndex] == "0")//测试已经完成，可以开始取盘 HasPallet && !HasPallentTest && dilist[PT.TK_DIIndex] == "1"
                        //if (!device.HasPalletTest && device.dilist[PT.TK_DIIndex] == "1" && device.dilist[PT.YH_DIIndex] == "0")//屏蔽是否有盘信号 弹开到位device.dilist[PT.TK_DIIndex] 压合到位device.dilist[PT.YH_DIIndex]
                        {
                            if (data.data.floor_status == 3)
                            {
                                if (data.data.load_status == 50 || data.data.load_status == 60 || data.data.load_status == 61)
                                {
                                    string sOperation = "";
                                    if (data.data.load_status == 50)
                                    {
                                        sOperation = "FORMN";
                                    }
                                    else if (data.data.load_status == 60)
                                    {
                                        sOperation = "CAPAC1";
                                    }
                                    else if (data.data.load_status == 61)
                                    {
                                        sOperation = "CAPAC6";
                                    }

                                    MsgRsp enddata = CallWCSClass.SetFormAGDGTestEnd(sOperation, data.data.tray_code, DateTime.Now);
                                }
                                CallWCSClass.UpdateFloorStatus(data.data.id, 1);//更新对应id库位状态信息 0未知，1可取，2可放，3工作中
                            }
                        }

                        if (data.data.get_put_req == 1)
                        {

                            if (device.NeedTakePallet() && device.dilist[PT.YH_DIIndex] == "0")//再次判断是否允许取盘
                            //if (!device.HasPalletTest && device.dilist[PT.TK_DIIndex] == "1" && device.dilist[PT.YH_DIIndex] == "0")
                            {
                                CallWCSClass.UpdateGetPutAns(data.data.id, 1);//2放盘，1取盘
                            }
                        }

                        if (data.data.get_put_req == 21)//已经取走托盘
                        {
                            WarehouseSrv.MsgRsp rsp = CallWCSClass.UpdateFloorStatus(data.data.id, 0);//更新对应id库位状态信息 0未知，1可取，2可放，3工作中
                            if (rsp != null && rsp.result)
                            {
                                MsgPumpClass.PublishMsg("TakePalletComplete", device);//取走托盘
                                PublicClass.WriteLog2DB(device.DeviceNo + "取盘完毕", PublicClass.LogContentType.Dispatcher);
                                return true;
                            }
                        }

                    }
                }
                catch (Exception ee)
                {
                    PublicClass.WriteLog("PutTakeClass.TakePallet：" + ee.Message);
                }
            }
            return false;
        }

        /// <summary>
        /// 更新库位信息到WCS
        /// 消防门、库位报警、库位烟感
        /// </summary>
        /// <param name="device"></param>
        /// <param name="data"></param>
        private static void UpdateInfoToWCS(DeviceClass device, WarehouseSrv.FormFloor data)
        {
            //CallWCSClass.UpdateDoorInduction(data.id, device.dilist[PT.FCDoorOpenedInPlace] == "1" ? 0 : 1);//更新消防门信息 0 表示消防门开，RGV可以通行
            CallWCSClass.UpdateDoorInduction(data.id, device.dilist[FCDoorOpenedInPlace] == "1" ? 0 : 1);

            if (string.IsNullOrWhiteSpace(device.Abnormal) || device.Abnormal == "---")//更新库位报警信息
                CallWCSClass.UpdateMacAlarm(data.id, "");
            else
                CallWCSClass.UpdateMacAlarm(data.id, device.Abnormal);

            //bool bSmoke = (device.dilist[PT.Smoke1Index] == "1" || device.dilist[PT.Smoke2Index] == "1" || device.dilist[PT.COSmokeIndex] == "1");//烟雾1  烟雾2  CO烟感
            bool bSmoke = (device.dilist[Smoke1Index] == "1" || device.dilist[Smoke2Index] == "1" || device.dilist[COSmokeIndex] == "1");
            CallWCSClass.UpdateNeedleBedSmoke(data.id, bSmoke ? 1 : 0);//更新库位烟感信息
        }

        /// <summary>
        /// 获取设备
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private static DeviceClass GetDeviceByID(int id)
        {
            return PublicClass.GetDevice_WarehouseNo(id.ToString());
        }

        /// <summary>
        /// 获取电池
        /// </summary>
        /// <param name="strPalletNo"></param>//由string strPalletNo改为DeviceClass device.PalletNo
        /// <returns></returns>
        public static Dictionary<int, string> GetBatteryNo(string strPalletNo)
        {
            try
            {
                CallWCSClass.InitPalletSrv();
                CallWCSClass.InitWarehouseSrv();
                PalletSrv.ctTrayDataRsp data = CallWCSClass.GetTrayInfo(strPalletNo);
                CallWCSClass.InitPalletSrv();
                CallWCSClass.InitWarehouseSrv();
                PalletSrv.ctMsgRspResult ngdata = CallWCSClass.GetTestResultOperationAll(strPalletNo);
                Dictionary<int, string> dic = new Dictionary<int, string>();
                if (data != null)
                {
                    foreach (PalletSrv.ctTray_batt_table t in data.data.batt_code)
                    {
                        PalletSrv.ctMsgRspBattStatus battcodeData = CallWCSClass.GetkBattCodeStatus(t.battcode);//电芯状态检测，不一样的电芯就不测
                        if (battcodeData != null && battcodeData.battoperation == data.data.test_status)
                        {
                            dic.Add(t.id - 1, t.battcode);
                        }
                    }
                }
                //有ng结果的电池条码剔除，但复测时不剔除
                if (ngdata != null && data.data.test_type == 0)
                {
                    foreach (PalletSrv.ctBattTestDataResult t in ngdata.TestResult)
                    {
                        PublicClass.WriteLog(string.Format("t ={0},{1},{2},{3},{4},{5},{6}" , t.batt_code,t.ag_result,t.ic_result,t.ic_result,t.ocv1_result,t.ocv2_result,t.dcr_result));
                        if (t.ic_result == "0" || t.ag_result == "0" || t.dg_result == "0" || t.ocv1_result == "1" || t.ocv2_result == "1" || t.dcr_result == "0")
                        {
                            //var key = dic.FirstOrDefault(q => q.Value == t.batt_code).Key;
                            //dic.Remove(key);
                            int keyToRemove = -1;
                            foreach (KeyValuePair<int, string> kvp in dic)
                            {
                                if (kvp.Value == t.batt_code)
                                {
                                    keyToRemove = kvp.Key;
                                    break;
                                }
                                PublicClass.WriteLog("kvp.Key =" + kvp.Key);
                            }
                            PublicClass.WriteLog("keyToRemove =" + keyToRemove);
                            if (keyToRemove != -1)
                            {
                                dic.Remove(keyToRemove);
                            }
                        }
                    }
                }
                return dic;
            }
            catch (Exception e)
            {
                PublicClass.WriteLog2DB(strPalletNo + "GetBatteryNo调用失败" + e.Message, PublicClass.LogContentType.Dispatcher);
                PublicClass.WriteLog(strPalletNo + "GetBatteryNo调用失败：" + e.Message);
                return null;
            }
        }

        public static string GetProcessFlowFromMES(DeviceClass device)
        {
            string strFlow = "";
            try
            {
                
                Msg10001 msg1 = new Msg10001();
                msg1.FACTORY_ID = 工厂;
                msg1.LINE_ID = 生产线;
                msg1.WORK_ID = GetWorkID(PublicClass.projectConfig.system.DeviceType, device.PalletNo);
                msg1.RESOURCECODE = device.DeviceNo;
                msg1.DEIVCECODE = GetDeviceCode(PublicClass.projectConfig.system.DeviceType);
                msg1.CARRIER_ID = device.PalletNo;
                msg1.SN = "";
                msg1.WORK_NO = PublicClass.currentUser.Username;
                msg1.SEND_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                string postData = JsonConvert.SerializeObject(msg1);
                string result = CallMESClass.PostUrl(url10001, postData);
                Dictionary<string, string> dic_ret = new Dictionary<string, string>();
                dic_ret = CallMESClass.JsonToDictionary(result);

                if (dic_ret["RESULT"].ToLower() == "true")
                {
                    strFlow = dic_ret["MESSAGE"];
                }
                PublicClass.WriteLog("GetProcessFlowFromMES return :" + dic_ret + ",strFlow = " + strFlow);
                
            }
            catch (Exception e)
            {
                PublicClass.WriteLog("GetProcessFlowFromMES：" + e.Message);
            }
            return strFlow;

        }
        /// <summary>
        /// 获取工艺流程
        /// </summary>
        public static string GetProcessFlow(DeviceClass device)
        {
            try
            {
                string strFlow = GetProcessFlowFromMES(device);
                PalletSrv.ctTrayDataRsp trayData = CallWCSClass.GetTrayInfo(device.PalletNo);
                if (trayData != null)
                {
                    if (trayData.data.test_status == 60 && trayData.data.test_type == 0)
                    {
                        if (strFlow == RLCS || strFlow == "此功能未启用，请使用本地控制！")
                            return RLCS;
                    }
                    else if (trayData.data.test_status == 60 && trayData.data.test_type == 1)//test_type == 1时为容量复测
                    {
                        if (strFlow == RLCSFC || strFlow == "此功能未启用，请使用本地控制！")
                            return RLCSFC;
                    }
                    else if (trayData.data.test_status == 61)
                    {
                        if (strFlow == DGCS || strFlow == "此功能未启用，请使用本地控制！")
                            return DGCS;
                    }
                    else if (trayData.data.test_type == 2)//test_type == 1时为简容量复测
                    {
                        if (strFlow == JRLFC || strFlow == "此功能未启用，请使用本地控制！")
                            return JRLFC;
                    }
                    else
                    {
                        return null;
                    }
                }
                return null;
            }
            catch (Exception e)
            {
                PublicClass.WriteLog("GetProcessFlow：" + e.Message);
                return null;
            }
            
        }

        /// <summary>
        /// 获取托盘类型
        /// </summary>
        /// <param name="strPalletNo"></param>//由string strPalletNo改为DeviceClass device.PalletNo
        /// <returns></returns>
        public static int GetPalletType(string strPalletNo)
        {
            PalletSrv.ctTrayDataRsp ret = CallWCSClass.GetTrayInfo(strPalletNo);
            if (ret != null && ret.result)
            {
                int nPalletType = ret.data.test_status;//托盘类型

                if (nPalletType == 50 || nPalletType == 60 || nPalletType == 61)//电池托盘
                    return 0;
                else if (nPalletType == 78 || nPalletType == 70)//并联精度工装&串联精度工装
                    return 1;//校准工装&计量工装&DCIR工装
                else if (nPalletType == 79)//线序工装
                    return 3;
                else if (nPalletType == 73)//负压工装
                    return 4;
                else if (nPalletType == 76)//拔吸嘴工装
                    return 5;
                else if (nPalletType == 75)//插吸嘴工装
                    return 6;
                else if (nPalletType == 71)//温度工装
                    return 7;
            }

            return 0;
        }

        /// <summary>
        /// 获取某个测试的中所有NG的电池条码
        /// 可以通过查询某个电池的条码是否在这个返回的列表中来判断电池是否NG
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static List<string> GetNGBatteryNo(TestDataClass data)
        {
            string strSQL1 = "select BatteryNo from " + DBClass.strNGTableName;
            strSQL1 += " where SoeTime>='" + data.StartTestTime + "' and SoeTime<='" + data.EndTestTime + "' and SoeFlag='100002' and DeviceNo='" + data.DeviceNo + "'";
            List<List<string>> list2D = DBClass.ExecuteSQL_Query(strSQL1);
            List<string> list_ng = new List<string>();
            foreach (List<string> list in list2D)
            {
                string No = list[0];
                list_ng.Add(No);
            }
            return list_ng;
        }

        /// <summary>
        /// 判断DCIR测试是否NG
        /// </summary>
        private static bool CheckDCIR(DCIRTestResultClass data)
        {
            DCIRConfigClass dcirconfig = PublicClass.ReadDeserializeObject<DCIRConfigClass>(PublicClass.InfoDir + "dcirconfig.json", true);
            if (data.I1 == 0)
            {
                return false;
            }
            if (dcirconfig.bTwoTest)
            {
                if (data.DCIR >= dcirconfig.DCIRThresold1 && data.DCIR <= dcirconfig.DCIRThresold2 && data.DCIR2 >= dcirconfig.DCIRThresold1 && data.DCIR2 <= dcirconfig.DCIRThresold2)
                    return true;
                else
                    return false;
            }
            else
            {
                if (data.DCIR >= dcirconfig.DCIRThresold1 && data.DCIR <= dcirconfig.DCIRThresold2)
                    return true;
                else
                    return false;
            }
        }
        static Dictionary<string, string> JsonToDictionary(string jsonData)
        {
            //实例化JavaScriptSerializer类的新实例
            JavaScriptSerializer jss = new JavaScriptSerializer();
            try
            {
                //将指定的 JSON 字符串转换为 Dictionary<string, object> 类型的对象
                return jss.Deserialize<Dictionary<string, string>>(jsonData);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private static string GetWorkID(int DeviceType, string PalletNo)
        {
            switch (DeviceType)
            {
                case 0: return 工序_化成;
                case 1:
                    {
                        PalletSrv.ctTrayDataRsp trayData = CallWCSClass.GetTrayInfo(PalletNo);
                        if (trayData.data.test_status == 60 && trayData.data.test_type == 0)
                        {

                            return 工序_分容;
                        }
                        else if (trayData.data.test_status == 60 && trayData.data.test_type == 1)//test_type == 1时为复测
                        {

                            return 工序_复测;
                        }
                        else if (trayData.data.test_status == 61)
                        {
                            return 工序_补电;
                        }
                        else if (trayData.data.test_type == 2)
                        {
                            return 工序_复测; //待确定
                        }
                        else
                            return 工序_分容;
                    }
                case 2: return 工序_DCIR;
                default: return "";
            }
            
        }
        private static string GetDeviceCode(int DeviceType)
        {
            switch (DeviceType)
            {
                case 0: return 设备编号_化成;
                case 1: return 设备编号_分容;
                case 2: return 设备编号_DCIR;
                default: return "";
            }

        }
        

        private static string GetBatteryResult(TestDataClass data,string BatteryNo)
        {
            List<string> nglist = GetNGBatteryNo(data);//NG数据
            if (nglist.Contains(BatteryNo))
            {
                return "NG";
            }
            else
            {
                return "OK";
            }
        }
        #region 获取测试数据中的统计数据信息
        /// <summary>
        /// 获得预充数据/分容数据/DCIR数据（DCIR数据好像不使用testdata，待定）
        /// </summary>
        /// <param name="testdata"></param>
        /// <returns></returns>
        public static List<object> GetData(TestDataClass testdata)
        {
            //DeviceClass device = GetDeviceByID(testdata.DeviceNo);
            DeviceClass device = PublicClass.GetDevice(testdata.DeviceNo);

            List<object> objlist = new List<object>();

            for (int i = 0; i < testdata.ChannelNoList.Count; i++)
            {
                List<Dictionary<string, object>> list = GetStepDatas(testdata, i);
                foreach (Dictionary<string, object> stepdic in list)
                {
                    Dictionary<string, object> dic = new Dictionary<string, object>();

                    foreach (var item in stepdic)
                    {
                        dic.Add(item.Key, item.Value);
                    }

                    objlist.Add(dic);
                }
            }
            return objlist;
        }

        public static List<object> GetData(TestDataClass testdata,int index)
        {
            DeviceClass device = PublicClass.GetDevice(testdata.DeviceNo);

            List<object> objlist = new List<object>();


            List<Dictionary<string, object>> list = GetStepDatas(testdata, index);
            foreach (Dictionary<string, object> stepdic in list)
            {
                Dictionary<string, object> dic = new Dictionary<string, object>();

                foreach (var item in stepdic)
                {
                    dic.Add(item.Key, item.Value);
                }                
                objlist.Add(dic);
            }

            return objlist;
        }

        private static List<Dictionary<string, object>> GetStepDatas(TestDataClass testdata, int index)
        {
            List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();

            int nChannelNo = PublicClass.ToInt(testdata.ChannelNoList[index]);
            string strDataFilePath = PublicClass.GetDataFilePath(testdata, nChannelNo); //拿到一个电池的测试统计信息csv文件            

            string[] strKeys0 = new string[] {
            "StepNo", "StepName", "StartVoltage", "EndVoltage", "MidVoltage", "StartCurrent" ,
            "EndCurrent","StartTemp","EndTemp","AvgTemp","EnvirentStartTemp","EnvirentEndTemp","EndCapcity",
            "EndEnergy","StartPressure","EndPressure","StartTime","EndTime","StartContractRes","RecordTime",
            "AvgPressure","MaxTemp", "MinTemp", "MaxContractRes"};
            string[] strKeys1 = new string[] {
            "StepNo", "StepName", "StartVoltage", "EndVoltage", "MidVoltage", "StartCurrent" ,
            "EndCurrent","StartTemp","EndTemp","AvgTemp","EnvirentStartTemp","EnvirentEndTemp","EndCapcity",
            "EndEnergy","StartContractRes","ReducedCapacity","StartTime","EndTime","RecordTime",
            "MaxTemp", "MinTemp","MaxContractRes"};
            string[] strKeys2 = new string[] {
            "StepNo", "StepName", "StartVoltage", "EndVoltage", "StartCurrent" ,
            "EndCurrent","StartTemp","EndTemp","StartTime","EnvirentStartTemp","EnvirentEndTemp","EndTime",
            "TestResult","AvgTemp","StartPositiveTemp","MaxPositiveTemp", "StartNegativeTemp",
            "MaxNegativeTemp","ContactRes","CabRes"};
            if (PublicClass.projectConfig.system.DeviceType == 0)
            {
                List<List<string>> listPreChargeData = StatisticsOneBatteryYC(strDataFilePath);//提取预充数据
                foreach (var item in listPreChargeData)
                {
                    Dictionary<string, object> dic = new Dictionary<string, object>();//每一个工步对应dic
                    for (int i = 0; i < item.Count; i++)
                    {
                        dic.Add(strKeys0[i], item[i]);
                    }
                    list.Add(dic);
                }
            }
            else if (PublicClass.projectConfig.system.DeviceType == 1)
            {
                List<List<string>> listFRResultData = StatisticsOneBatteryFR(strDataFilePath);//提取分容数据
                foreach (var item in listFRResultData)
                {
                    Dictionary<string, object> dic = new Dictionary<string, object>();
                    for (int i = 0; i < item.Count; i++)
                    {
                        dic.Add(strKeys1[i], item[i]);
                    }
                    list.Add(dic);
                }
            }
            else if (PublicClass.projectConfig.system.DeviceType == 2)
            {
                List<List<string>> listDCIRResultData = StatisticsOneBatteryDCIR(strDataFilePath);//提取DCIR数据
                foreach (var item in listDCIRResultData)
                {
                    Dictionary<string, object> dic = new Dictionary<string, object>();
                    for (int i = 0; i < item.Count; i++)
                    {
                        dic.Add(strKeys2[i], item[i]);
                    }
                    dic.Add("DCIR_Value", GetDCIR(testdata.BatteryNoList[index]));
                    list.Add(dic);
                }
            }


            return list;
        }

        /// <summary>
        /// 统计电池的相关测试信息（预充数据）
        /// </summary>
        /// <param name="vallist0"></param>
        /// <param name="strDataFilePath"></param>
        /// <param name="nStep"></param>
        /// <returns></returns>
        private static List<List<string>> StatisticsOneBatteryYC(string strDataFilePath)
        {
            List<List<string>> vallist2D = new List<List<string>>();

            try
            {
                string strLastStepIndex = "";
                long nStartTime = 0;
                long nEndTime = 0;
                string strEndTime = "";//结束时间
                string strEndV = "";//结束电压
                string strEndC = "";//结束电流
                string strEndCap = "";//结束容量
                string strEndE = "";//结束能量
                string strEndT = "";//结束温度
                string strEndDeviceT = "";//库位结束温度
                string strNegPressure = "";//结束真空度
                List<double> TList = new List<double>();//用于计算平均温度
                List<double> NegPressureList = new List<double>();//用于计算平均真空度
                double maxT = 0;//计算最大温度
                double minT = 1000;//计算最小温度
                double maxContactImpedance = 0;//最大接触电阻
                string strPreviousCI = "";


                //电压、容量的列表，用于求取中值电压
                List<KeyValuePair<string, double>> V_Cap_List = new List<KeyValuePair<string, double>>();

                using (FileStream fs = new FileStream(strDataFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))//创建负责读取的流，将创建文件流对象的过程写在using当中，会自动的帮助我们释放流所占用的资源
                {
                    using (StreamReader sr = new StreamReader(fs))//使用StreamReader来读取一个文本文件
                    {
                        List<string> strlines = new List<string>();//csv初始全部数据
                        List<string> strlinesSelect = new List<string>();//筛选后的数据
                        while (!sr.EndOfStream)//使用 EndOfStream 属性可以检查文件的末尾
                            strlines.Add(sr.ReadLine());//从流中读取一行字符并将数据作为字符串返回  .ReadToEnd()读取全部
                        for (int index = 0; index < strlines.Count; index++)
                        {
                            string strline = strlines[index];
                            string[] strdatas = strline.Split(',');
                            if (strdatas.Length > 2)
                            {
                                if (strdatas[2] != "0" && strdatas[15] != "0")//过滤工步时间为0和工步类型为0的两种数据
                                {
                                    strlinesSelect.Add(strlines[index]);
                                }
                            }
                        }
                        for (int index = 0; index < strlinesSelect.Count; index++)
                        {
                            string strline = strlinesSelect[index];
                            string[] strdatas = strline.Split(',');
                            string strCurrentStepType = strdatas[15];// "工步类型"

                            if (PublicClass.FilterDurationIs0Data(strdatas))//工步执行时间等于0的情况，直接过滤掉
                                continue;
                            if (PublicClass.GetAIFromStrs(strdatas, "工步类型") == "0")//工步类型为0的情况，过滤掉
                                continue;

                            if (strCurrentStepType != "0")//工步类型号为0的时候  不用
                            {
                                string strStepIndex = strdatas[14];// "工步序号
                                string strCI = GetContactImpedance(strdatas);//接触电阻                                
                                if (strPreviousCI == "正无穷大")
                                {
                                    vallist2D.Last()[18] = strCI;
                                }
                                strPreviousCI = strCI;

                                if (strLastStepIndex != strStepIndex)//工步号变化了,即记录该工步号的第一条记录为开始数据
                                {
                                    strLastStepIndex = strStepIndex;
                                    List<string> vallist = new List<string>();

                                    vallist.Add(strStepIndex);//工步号
                                    vallist.Add(StepClass.GetStepTypeName(strCurrentStepType));//工步类型
                                    vallist.Add(strdatas[4]);//开始电压
                                    vallist.Add("---");//结束电压
                                    vallist.Add("---");//中值电压
                                    vallist.Add(strdatas[6]);//开始电流
                                    vallist.Add("---");//结束电流
                                    vallist.Add(strdatas[10]);//开始温度
                                    vallist.Add("---");//结束温度
                                    vallist.Add("---");//平均温度
                                    vallist.Add(strdatas[17]);//库位开始温度
                                    vallist.Add("---");//库位结束温度
                                    vallist.Add("---");//结束容量
                                    vallist.Add("---");//结束能量
                                    vallist.Add(strdatas[16]);//开始真空度(原无)
                                    vallist.Add("---");//结束真空度
                                    vallist.Add(strdatas[0]);//开始时间
                                    vallist.Add("---");//结束时间
                                    vallist.Add(strCI);//开始接触电阻（第一条数据为正无穷大，需读取第二条）
                                    vallist.Add("---");//持续时间
                                    vallist.Add("---");//平均真空度
                                    vallist.Add("---");//最大温度
                                    vallist.Add("---");//最小温度
                                    vallist.Add("---");//最大接触电阻


                                    if (vallist2D.Count > 0)//已赋值的开始数据跳过
                                    {
                                        int tempindex = 0;
                                        tempindex++;//工步号
                                        tempindex++;//工步类型
                                        tempindex++;//开始电压
                                        vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                        vallist2D.Last()[tempindex++] = CalcMidCapV(V_Cap_List);//中值电压
                                        tempindex++;//开始电流
                                        vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                        tempindex++;//开始温度
                                        vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                        vallist2D.Last()[tempindex++] = TList.Average().ToString("F1");//平均温度
                                        tempindex++;//库位开始温度
                                        vallist2D.Last()[tempindex++] = strEndDeviceT;//库位结束温度
                                        vallist2D.Last()[tempindex++] = strEndCap;//结束容量
                                        vallist2D.Last()[tempindex++] = strEndE;//结束能量
                                        tempindex++;//开始真空度(原无)
                                        vallist2D.Last()[tempindex++] = strNegPressure;//结束真空度
                                        tempindex++;//开始时间
                                        vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                        tempindex++;//开始接触电阻
                                        vallist2D.Last()[tempindex++] = PublicClass.MillisecondsToTimeSpanStr(nEndTime - nStartTime + 1000);//持续时间
                                        vallist2D.Last()[tempindex++] = NegPressureList.Average().ToString("F1");//平均真空度
                                        vallist2D.Last()[tempindex++] = maxT.ToString("F1");//最大温度
                                        vallist2D.Last()[tempindex++] = minT.ToString("F1");//最小温度
                                        vallist2D.Last()[tempindex++] = maxContactImpedance.ToString("F1");//最大接触电阻

                                        V_Cap_List.Clear();
                                        NegPressureList.Clear();
                                        TList.Clear();
                                    }

                                    nStartTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                    vallist2D.Add(vallist);
                                }

                                //结束数据，之后的每一次循环读取下一条数据并赋值结束数据
                                nEndTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                strEndTime = strdatas[0];// 数据时间
                                strEndV = strdatas[4];//电压
                                strEndC = strdatas[6];//电流
                                strEndT = strdatas[10];//温度
                                strEndDeviceT = strdatas[17];//库位温度
                                strEndCap = strdatas[7];//容量
                                strEndE = strdatas[8];//能量
                                V_Cap_List.Add(new KeyValuePair<string, double>(strEndV, PublicClass.ToDouble(strEndCap)));
                                strNegPressure = strdatas[16];//真空度
                                NegPressureList.Add(PublicClass.ToDouble(strNegPressure));
                                TList.Add(PublicClass.ToDouble(strEndT));
                                double t = PublicClass.ToDouble(strEndT);
                                if (maxT < t)
                                    maxT = t;
                                if (minT > t)
                                    minT = t;
                                double ci = PublicClass.ToDouble(strCI);
                                if (maxContactImpedance < ci)
                                    maxContactImpedance = ci;
                            }



                            if (index == strlinesSelect.Count - 1)//最后一行数据
                            {
                                if (vallist2D.Count > 0)
                                {
                                    int tempindex = 0;
                                    tempindex++;//工步号
                                    tempindex++;//工步类型
                                    tempindex++;//开始电压
                                    vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                    vallist2D.Last()[tempindex++] = CalcMidCapV(V_Cap_List);//中值电压
                                    tempindex++;//开始电流
                                    vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                    tempindex++;//开始温度
                                    vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                    vallist2D.Last()[tempindex++] = strEndT;//平均温度
                                    tempindex++;//库位开始温度
                                    vallist2D.Last()[tempindex++] = strEndDeviceT;//库位结束温度
                                    vallist2D.Last()[tempindex++] = strEndCap;//结束容量
                                    vallist2D.Last()[tempindex++] = strEndE;//结束能量
                                    tempindex++;//开始真空度(原无)
                                    vallist2D.Last()[tempindex++] = strNegPressure;//结束真空度
                                    tempindex++;//开始时间
                                    vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                    tempindex++;//开始接触电阻
                                    vallist2D.Last()[tempindex++] = PublicClass.MillisecondsToTimeSpanStr(nEndTime - nStartTime + 1000);//持续时间
                                    vallist2D.Last()[tempindex++] = NegPressureList.Average().ToString("F1");//平均真空度
                                    vallist2D.Last()[tempindex++] = maxT.ToString("F1");//最大温度
                                    vallist2D.Last()[tempindex++] = minT.ToString("F1");//最小温度
                                    vallist2D.Last()[tempindex++] = maxContactImpedance.ToString("F1");//最大接触电阻
                                }
                            }

                        }
                    }
                }
            }
            catch (Exception ee)
            {
                PublicClass.WriteLog("StatisticsOneBattery:" + ee.Message);
            }

            return vallist2D;
        }
        public static string ReducedCapacityFormula = "";
        /// <summary>
        /// 统计电池的相关测试信息（分容数据）
        /// </summary>
        private static List<List<string>> StatisticsOneBatteryFR(string strDataFilePath)
        {
            List<List<string>> vallist2D = new List<List<string>>();

            try
            {
                string strLastStepIndex = "";
                long nStartTime = 0;
                long nEndTime = 0;
                string strEndTime = "";//结束时间
                string strEndV = "";//结束电压
                string strEndC = "";//结束电流
                string strEndCap = "";//结束容量
                string strEndE = "";//结束能量
                string strEndT = "";//结束温度
                string strEndDeviceT = "";//库位结束温度
                List<double> TList = new List<double>();//用于计算平均温度
                double maxT = 0;//计算最大温度
                double minT = 1000;//计算最小温度
                double maxContactImpedance = 0;//最大接触电阻
                string strPreviousCI = "";//记录上一次接触电阻
                string strReducedCapacity = "";//折算容量


                //电压、容量的列表，用于求取中值电压
                List<KeyValuePair<string, double>> V_Cap_List = new List<KeyValuePair<string, double>>();

                using (FileStream fs = new FileStream(strDataFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))//创建负责读取的流，将创建文件流对象的过程写在using当中，会自动的帮助我们释放流所占用的资源
                {
                    using (StreamReader sr = new StreamReader(fs))//使用StreamReader来读取一个文本文件
                    {
                        List<string> strlines = new List<string>();//csv初始全部数据
                        List<string> strlinesSelect = new List<string>();//筛选后的数据
                        while (!sr.EndOfStream)//使用 EndOfStream 属性可以检查文件的末尾
                            strlines.Add(sr.ReadLine());//从流中读取一行字符并将数据作为字符串返回  .ReadToEnd()读取全部
                        for (int index = 0; index < strlines.Count; index++)
                        {
                            string strline = strlines[index];
                            string[] strdatas = strline.Split(',');
                            if (strdatas.Length > 2)
                            {
                                if (strdatas[2] != "0" && strdatas[15] != "0")//过滤工步时间为0和工步类型为0的两种数据
                                {
                                    strlinesSelect.Add(strlines[index]);
                                }
                            }
                        }
                        for (int index = 0; index < strlinesSelect.Count; index++)
                        {
                            string strline = strlinesSelect[index];
                            string[] strdatas = strline.Split(',');
                            string strCurrentStepType = strdatas[15];// "工步类型"

                            if (PublicClass.FilterDurationIs0Data(strdatas))//工步执行时间等于0的情况，直接过滤掉
                                continue;
                            if (PublicClass.GetAIFromStrs(strdatas, "工步类型") == "0")//工步类型为0的情况，过滤掉
                                continue;


                            if (strCurrentStepType != "0")//工步类型号为0的时候  不用
                            {
                                string strStepIndex = strdatas[14];// "工步序号
                                string strCI = GetContactImpedance(strdatas);//接触电阻
                                if (strPreviousCI == "正无穷大")
                                {
                                    vallist2D.Last()[14] = strCI;
                                }
                                strPreviousCI = strCI;

                                if (strLastStepIndex != strStepIndex)//工步号变化了,即记录该工步号的第一条记录为开始数据
                                {
                                    strLastStepIndex = strStepIndex;
                                    List<string> vallist = new List<string>();

                                    vallist.Add(strStepIndex);//工步号
                                    vallist.Add(StepClass.GetStepTypeName(strCurrentStepType));//工步类型
                                    vallist.Add(strdatas[4]);//开始电压
                                    vallist.Add("---");//结束电压
                                    vallist.Add("---");//中值电压
                                    vallist.Add(strdatas[6]);//开始电流
                                    vallist.Add("---");//结束电流
                                    vallist.Add(strdatas[10]);//开始温度
                                    vallist.Add("---");//结束温度
                                    vallist.Add("---");//平均温度
                                    vallist.Add(strdatas[17]);//库位开始温度
                                    vallist.Add("---");//库位结束温度
                                    vallist.Add("---");//结束容量
                                    vallist.Add("---");//结束能量
                                    vallist.Add(strCI);//开始接触电阻
                                    vallist.Add("---");//折算容量（使用获取的公式计算）
                                    vallist.Add(strdatas[0]);//开始时间
                                    vallist.Add("---");//结束时间
                                    vallist.Add("---");//持续时间
                                    vallist.Add("---");//最大温度
                                    vallist.Add("---");//最小温度
                                    vallist.Add("---");//最大接触电阻


                                    if (vallist2D.Count > 0)//已赋值的跳过
                                    {
                                        int tempindex = 0;
                                        tempindex++;//工步号
                                        tempindex++;//工步类型
                                        tempindex++;//开始电压
                                        vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                        vallist2D.Last()[tempindex++] = CalcMidCapV(V_Cap_List);//中值电压
                                        tempindex++;//开始电流
                                        vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                        tempindex++;//开始温度
                                        vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                        vallist2D.Last()[tempindex++] = TList.Average().ToString("F1");//平均温度
                                        tempindex++;//库位开始温度
                                        vallist2D.Last()[tempindex++] = strEndDeviceT;//库位结束温度
                                        vallist2D.Last()[tempindex++] = strEndCap;//结束容量
                                        vallist2D.Last()[tempindex++] = strEndE;//结束能量
                                        tempindex++;//开始接触电阻
                                        vallist2D.Last()[tempindex++] = strReducedCapacity;//折算容量
                                        tempindex++;//开始时间
                                        vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                        vallist2D.Last()[tempindex++] = PublicClass.MillisecondsToTimeSpanStr(nEndTime - nStartTime + 1000);//持续时间
                                        vallist2D.Last()[tempindex++] = maxT.ToString("F1");//最大温度
                                        vallist2D.Last()[tempindex++] = minT.ToString("F1");//最小温度
                                        vallist2D.Last()[tempindex++] = maxContactImpedance.ToString("F1");//最大接触电阻

                                        V_Cap_List.Clear();
                                        TList.Clear();
                                    }

                                    nStartTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                    vallist2D.Add(vallist);
                                }
                                //结束数据
                                nEndTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                strEndTime = strdatas[0];// 数据时间
                                strEndV = strdatas[4];//电压
                                strEndC = strdatas[6];//电流
                                strEndT = strdatas[10];//温度
                                strEndDeviceT = strdatas[17];//库位温度
                                strEndCap = strdatas[7];//容量
                                strEndE = strdatas[8];//能量
                                V_Cap_List.Add(new KeyValuePair<string, double>(strEndV, PublicClass.ToDouble(strEndCap)));
                                TList.Add(PublicClass.ToDouble(strEndT));
                                double t = PublicClass.ToDouble(strEndT);
                                if (maxT < t)
                                    maxT = t;
                                if (minT > t)
                                    minT = t;
                                double ci = PublicClass.ToDouble(strCI);
                                if (maxContactImpedance < ci)
                                    maxContactImpedance = ci;
                                string str = ReducedCapacityFormula.Replace(" ", "").Replace("Cap", strEndCap.ToString()).Replace("T", strEndT.ToString());
                                var result = new DataTable().Compute(str, null);
                                strReducedCapacity = result.ToString();
                            }



                            if (index == strlinesSelect.Count - 1)
                            {
                                if (vallist2D.Count > 0)
                                {
                                    int tempindex = 0;
                                    tempindex++;//工步号
                                    tempindex++;//工步类型
                                    tempindex++;//开始电压
                                    vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                    vallist2D.Last()[tempindex++] = CalcMidCapV(V_Cap_List);//中值电压
                                    tempindex++;//开始电流
                                    vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                    tempindex++;//开始温度
                                    vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                    vallist2D.Last()[tempindex++] = strEndT;//平均温度
                                    tempindex++;//库位开始温度
                                    vallist2D.Last()[tempindex++] = strEndDeviceT;//库位结束温度
                                    vallist2D.Last()[tempindex++] = strEndCap;//结束容量
                                    vallist2D.Last()[tempindex++] = strEndE;//结束能量
                                    tempindex++;//开始接触电阻
                                    vallist2D.Last()[tempindex++] = strReducedCapacity;//折算容量
                                    tempindex++;//开始时间
                                    vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                    vallist2D.Last()[tempindex++] = PublicClass.MillisecondsToTimeSpanStr(nEndTime - nStartTime + 1000);//持续时间
                                    vallist2D.Last()[tempindex++] = maxT.ToString("F1");//最大温度
                                    vallist2D.Last()[tempindex++] = minT.ToString("F1");//最小温度
                                    vallist2D.Last()[tempindex++] = maxContactImpedance.ToString("F1");//最大接触电阻
                                }
                            }

                        }
                    }
                }
            }
            catch (Exception ee)
            {
                PublicClass.WriteLog("StatisticsOneBattery:" + ee.Message);
            }

            return vallist2D;
        }

        /// <summary>
        /// 求接触电阻
        /// </summary>
        private static string GetContactImpedance(string[] strdatas)
        {
            string strCurrentStepType = strdatas[15];// "工步类型"
            if (strCurrentStepType != "11")//搁置时不做计算
            {
                double lugV = PublicClass.ToDouble(strdatas[9]);//辅助电压
                double mainV = PublicClass.ToDouble(strdatas[4]);//电压
                double mainC = PublicClass.ToDouble(strdatas[6]);//电流

                double dContactImpedance = Math.Abs((lugV - mainV) * 1000 / mainC);
                return dContactImpedance.ToString("F2");
            }
            else
            {
                return "0";
            }
        }


        /// <summary>
        /// 求中值电压
        /// </summary>
        /// <param name="V_Cap_List"></param>
        /// <param name="lastCap"></param>
        /// <returns></returns>
        private static string CalcMidCapV(List<KeyValuePair<string, double>> V_Cap_List)
        {
            if (V_Cap_List != null && V_Cap_List.Count > 0)
            {
                double lastCap = V_Cap_List.Last().Value;
                if (lastCap > 5)
                {
                    double minCap = lastCap / 2;
                    foreach (var item in V_Cap_List)
                    {
                        if (item.Value > minCap && item.Value < lastCap)
                            return item.Key;
                    }
                }
            }

            return "0";
        }

        /// <summary>
        /// 取DCIR放电直流电阻
        /// </summary>
        private static string GetDCIR(string BatteryNo)
        {
            string strSQL1 = "select DCIR from " + DBClass.strDCIRTableName;
            strSQL1 += " where BatteryNo='" + BatteryNo + "'";
            List<List<string>> list2D = DBClass.ExecuteSQL_Query(strSQL1);
            List<string> list_value = new List<string>();
            foreach (List<string> list in list2D)
            {
                string value = list[0];
                list_value.Add(value);
            }
            return list_value[0];
        }

        /// <summary>
        /// 求回路电阻
        /// </summary>
        private static string GetLoopImpedance(string[] strdatas)//公式未知
        {
            string strCurrentStepType = strdatas[15];// "工步类型"
            if (strCurrentStepType != "11")//搁置时不做计算
            {
                double lugV = PublicClass.ToDouble(strdatas[9]);//辅助电压
                double mainV = PublicClass.ToDouble(strdatas[4]);//电压
                double mainC = PublicClass.ToDouble(strdatas[6]);//电流

                double dContactImpedance = Math.Abs((lugV - mainV) * 1000 / mainC);
                return dContactImpedance.ToString("F2");
            }
            else
            {
                return "0";
            }
        }

        /// <summary>
        /// 统计电池的相关测试信息（DCIR数据）//待处理事项：测试结果（暂无）、DCIR放电直流电阻（需要电池条码）、最大回路阻抗（公式不清楚）
        /// </summary>
        private static List<List<string>> StatisticsOneBatteryDCIR(string strDataFilePath)
        {
            List<List<string>> vallist2D = new List<List<string>>();

            try
            {
                string strLastStepIndex = "";
                long nStartTime = 0;
                long nEndTime = 0;
                string strEndTime = "";//结束时间
                string strEndV = "";//结束电压
                string strEndC = "";//结束电流
                string strEndT = "";//结束温度
                string strEndDeviceT = "";//库位结束温度
                List<double> TList = new List<double>();//用于计算平均温度
                double MaxPositiveTemp = 0;//工步通道正极最大温度
                double MaxNegativeTemp = 0;//工步通道负极最大温度
                double ContactRes = 0;//工步最大接触电阻
                double CabRes = 0;//工步最大回路阻抗


                //电压、容量的列表，用于求取中值电压
                List<KeyValuePair<string, double>> V_Cap_List = new List<KeyValuePair<string, double>>();

                using (FileStream fs = new FileStream(strDataFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))//创建负责读取的流，将创建文件流对象的过程写在using当中，会自动的帮助我们释放流所占用的资源
                {
                    using (StreamReader sr = new StreamReader(fs))//使用StreamReader来读取一个文本文件
                    {
                        List<string> strlines = new List<string>();//csv初始全部数据
                        List<string> strlinesSelect = new List<string>();//筛选后的数据
                        while (!sr.EndOfStream)//使用 EndOfStream 属性可以检查文件的末尾
                            strlines.Add(sr.ReadLine());//从流中读取一行字符并将数据作为字符串返回  .ReadToEnd()读取全部
                        for (int index = 0; index < strlines.Count; index++)
                        {
                            string strline = strlines[index];
                            string[] strdatas = strline.Split(',');
                            if (strdatas.Length > 2)
                            {
                                if (strdatas[2] != "0" && strdatas[15] != "0")//过滤工步时间为0和工步类型为0的两种数据
                                {
                                    strlinesSelect.Add(strlines[index]);
                                }
                            }
                        }
                        for (int index = 0; index < strlinesSelect.Count; index++)
                        {
                            string strline = strlinesSelect[index];
                            string[] strdatas = strline.Split(',');
                            string strCurrentStepType = strdatas[15];// "工步类型"

                            if (PublicClass.FilterDurationIs0Data(strdatas))//工步执行时间等于0的情况，直接过滤掉
                                continue;
                            if (PublicClass.GetAIFromStrs(strdatas, "工步类型") == "0")//工步类型为0的情况，过滤掉
                                continue;


                            if (strCurrentStepType != "0")//工步类型号为0的时候  不用
                            {
                                string strStepIndex = strdatas[14];// "工步序号
                                string strCI = GetContactImpedance(strdatas);//接触电阻
                                string strLI = GetLoopImpedance(strdatas);//回路电阻

                                if (strLastStepIndex != strStepIndex)//工步号变化了,即记录该工步号的第一条记录为开始数据
                                {
                                    strLastStepIndex = strStepIndex;
                                    List<string> vallist = new List<string>();

                                    vallist.Add(strStepIndex);//工步号
                                    vallist.Add(StepClass.GetStepTypeName(strCurrentStepType));//工步类型
                                    vallist.Add(strdatas[4]);//开始电压
                                    vallist.Add("---");//结束电压
                                    vallist.Add(strdatas[6]);//开始电流
                                    vallist.Add("---");//结束电流
                                    vallist.Add(strdatas[10]);//开始温度
                                    vallist.Add("---");//结束温度
                                    vallist.Add(strdatas[0]);//开始时间
                                    vallist.Add(strdatas[17]);//库位开始温度
                                    vallist.Add("---");//库位结束温度                                    
                                    vallist.Add("---");//结束时间
                                    vallist.Add("---");//测试结果【OK,NG】
                                    vallist.Add("---");//平均温度
                                    vallist.Add(strdatas[10]);//工步通道正极开始温度
                                    vallist.Add("---");//工步通道正极最大温度
                                    vallist.Add(strdatas[19]);//工步通道负极开始温度
                                    vallist.Add("---");//工步通道负极最大温度
                                    vallist.Add("---");//工步最大接触阻抗
                                    vallist.Add("---");//工步最大回路阻抗


                                    if (vallist2D.Count > 0)//已赋值的跳过
                                    {
                                        int tempindex = 0;
                                        tempindex++;//工步号
                                        tempindex++;//工步类型
                                        tempindex++;//开始电压
                                        vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                        tempindex++;//开始电流
                                        vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                        tempindex++;//开始温度
                                        vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                        tempindex++;//开始时间
                                        tempindex++;//库位开始温度
                                        vallist2D.Last()[tempindex++] = strEndDeviceT;//库位结束温度
                                        vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                        tempindex++;//测试结果【OK,NG】
                                        vallist2D.Last()[tempindex++] = TList.Average().ToString("F1");//平均温度
                                        tempindex++;//工步通道正极开始温度
                                        vallist2D.Last()[tempindex++] = MaxPositiveTemp.ToString("F1");//工步通道正极最大温度
                                        tempindex++;//工步通道负极开始温度
                                        vallist2D.Last()[tempindex++] = MaxNegativeTemp.ToString("F1");//工步通道负极最大温度
                                        vallist2D.Last()[tempindex++] = ContactRes.ToString("F1");//工步最大接触阻抗
                                        vallist2D.Last()[tempindex++] = CabRes.ToString("F1");//工步最大回路阻抗

                                        V_Cap_List.Clear();
                                        TList.Clear();
                                    }

                                    nStartTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                    vallist2D.Add(vallist);
                                }
                                //结束数据
                                nEndTime = PublicClass.ToLong(strdatas[2]);//工步执行时间
                                strEndTime = strdatas[0];// 数据时间
                                strEndV = strdatas[4];//电压
                                strEndC = strdatas[6];//电流
                                strEndT = strdatas[10];//温度
                                strEndDeviceT = strdatas[17];//库位温度
                                TList.Add(PublicClass.ToDouble(strEndT));
                                double ci = PublicClass.ToDouble(strCI);
                                if (ContactRes < ci)
                                    ContactRes = ci;
                                double li = PublicClass.ToDouble(strLI);
                                if (CabRes < li)
                                    CabRes = li;
                                double PositiveTemp = PublicClass.ToDouble(strdatas[10]);
                                if (MaxPositiveTemp < PositiveTemp)
                                    MaxPositiveTemp = PositiveTemp;
                                double NegativeTemp = PublicClass.ToDouble(strdatas[19]);
                                if (MaxNegativeTemp < NegativeTemp)
                                    MaxNegativeTemp = NegativeTemp;
                            }



                            if (index == strlinesSelect.Count - 1)
                            {
                                if (vallist2D.Count > 0)
                                {
                                    int tempindex = 0;
                                    tempindex++;//工步号
                                    tempindex++;//工步类型
                                    tempindex++;//开始电压
                                    vallist2D.Last()[tempindex++] = strEndV;//结束电压
                                    tempindex++;//开始电流
                                    vallist2D.Last()[tempindex++] = strEndC;//结束电流
                                    tempindex++;//开始温度
                                    vallist2D.Last()[tempindex++] = strEndT;//结束温度
                                    tempindex++;//开始时间
                                    tempindex++;//库位开始温度
                                    tempindex++;//库位结束温度
                                    vallist2D.Last()[tempindex++] = strEndTime;//结束时间
                                    tempindex++;//测试结果【OK,NG】
                                    vallist2D.Last()[tempindex++] = strEndT;//平均温度
                                    tempindex++;//工步通道正极开始温度
                                    vallist2D.Last()[tempindex++] = MaxPositiveTemp.ToString("F1");//工步通道正极最大温度
                                    tempindex++;//工步通道负极开始温度
                                    vallist2D.Last()[tempindex++] = MaxNegativeTemp.ToString("F1");//工步通道负极最大温度
                                    vallist2D.Last()[tempindex++] = ContactRes.ToString("F1");//最大接触电阻
                                    vallist2D.Last()[tempindex++] = CabRes.ToString("F1");//工步最大回路阻抗
                                }
                            }

                        }
                    }
                }
            }
            catch (Exception ee)
            {
                PublicClass.WriteLog("StatisticsOneBattery:" + ee.Message);
            }

            return vallist2D;
        }

        #endregion
        public static string InsertCSV(string Path)
        {
            string strContent = "";
            FileStream fs = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
            StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
            strContent = sr.ReadToEnd().ToString();
            sr.Close();
            string strColumns = "执行时间,工步号,时长,端口电压,通道电压,负电压,电流,容量,能量,辅助电压,电池温度1,第1层循环次序号,第2层循环次序号,总容量,工步号,工步类型,真空度,环境温度1,控制状态,电池温度2,环境温度2,保留1,保留2,保留3,保留4,保留5,保留6,保留7,保留8,类型";
            fs = new FileStream(PublicClass.TempDir + System.IO.Path.GetFileName(Path), FileMode.Create);
            StreamWriter sw = new StreamWriter(fs, Encoding.GetEncoding("GB2312"));
            sw.WriteLine(strColumns);
            sw.WriteLine(strContent);
            sw.Close();//写入
            return PublicClass.TempDir + System.IO.Path.GetFileName(Path);
        }

        public static string GetStartTime(List<object> list)
        {
            string ret = "";
            Dictionary<string, object> dictest = (Dictionary<string, object>)list[0];
            ret = dictest["StartTime"].ToString();
            PublicClass.WriteLog("GetStartTime = " + ret);
            return ret;
        }
        public static bool UploadMes(int DeviceType, List<object> datalist)
        {
            bool bRet = false;
            if (datalist != null && datalist.Count > 0)
            {
                for (int i = 0; i < datalist.Count; i++)
                {
                    if (datalist[i] is TestDataClass)
                    {

                        TestDataClass data = (TestDataClass)datalist[i];//全部数据
                        for (int j = 0; j < data.ChannelNoList.Count; j++)
                        {
                            string url = url10003;
                            int nChannelNo = PublicClass.ToInt(data.ChannelNoList[j]);
                            string strPath = InsertCSV(PublicClass.GetDataFilePath(data, nChannelNo));

                            Msg10003 msg = new Msg10003();
                            msg.FACTORY_ID = 工厂;
                            msg.LINE_ID = 生产线;
                            msg.WORK_ID = GetWorkID(DeviceType, data.PalletNo);
                            msg.RESOURCECODE = data.DeviceNo + "-" + data.ChannelNoList[j];
                            msg.DEIVCECODE = GetDeviceCode(DeviceType);
                            msg.CARRIER_ID = data.PalletNo;
                            msg.SN = data.BatteryNoList[j];
                            msg.WORK_NO = PublicClass.currentUser.Username;
                            msg.SEND_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            msg.FILENAME = Path.GetFileName(strPath);
                            Dictionary<string, string> dic = new Dictionary<string, string>();
                            dic = JsonToDictionary(JsonConvert.SerializeObject(msg));
                            foreach (var pair in dic)
                            {
                                url += string.Format("&{0}={1}", pair.Key, pair.Value);
                            }
                            string result = CallMESClass.UploadRequest(url, strPath, dic);
                            File.Delete(strPath);
                            Dictionary<string, string> dic_ret = new Dictionary<string, string>();
                            dic_ret = CallMESClass.JsonToDictionary(result);

                            if (dic_ret["RESULT"].ToLower() == "true")
                            {
                                strPath = dic_ret["MESSAGE"];
                                bRet = true;
                            }
                            else
                            {
                                bRet = false;
                            }
                            if (bRet)
                            {
                                Msg10002 msg1 = new Msg10002();
                                msg1.FACTORY_ID = 工厂;
                                msg1.LINE_ID = 生产线;
                                msg1.WORK_ID = GetWorkID(DeviceType, data.PalletNo);
                                msg1.RESOURCECODE = data.DeviceNo + "-" + data.ChannelNoList[j];
                                msg1.DEIVCECODE = GetDeviceCode(DeviceType);
                                msg1.CARRIER_ID = data.PalletNo;
                                msg1.SN = data.BatteryNoList[j];
                                msg1.PRODUCT_NUMBER = "1";
                                msg1.WORK_NO = PublicClass.currentUser.Username;
                                msg1.STATUS = GetBatteryResult(data, data.BatteryNoList[j]);
                                msg1.LOCATION = 所在位置;
                                msg1.FILEPATH = strPath;
                                msg1.DC_INFO = GetData(data, j);
                                msg1.SEND_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                msg1.COLL_TIME = GetStartTime(msg1.DC_INFO);
                                string postData = JsonConvert.SerializeObject(msg1);
                                result = CallMESClass.PostUrl(url10002, postData);

                                dic_ret = CallMESClass.JsonToDictionary(result);

                                if (dic_ret["RESULT"].ToLower() == "true")
                                {
                                    strPath = dic_ret["MESSAGE"];
                                    bRet = true;
                                }
                                else
                                {
                                    bRet = false;
                                }
                            }
                            if (bRet)
                            {
                                bool b = data.UpdateDataState("upload");//数据库中更新状态，表明已上传
                                if (b)
                                {
                                    PublicClass.WriteLog(data.PalletNo + "," + data.ChannelNoList[j] + "" + "MES数据上传");
                                    PublicClass.WriteLog2DB(data.PalletNo + "," + data.ChannelNoList[j] + "UploadMes调用成功", PublicClass.LogContentType.Dispatcher);
                                    PublicClass.WriteLog(data.PalletNo + "," + data.ChannelNoList[j] + "UploadMes调用成功");
                                }
                            }
                            else
                            {
                                PublicClass.WriteLog2DB(data.PalletNo + "," + data.ChannelNoList[j] + "UploadMes调用失败", PublicClass.LogContentType.Dispatcher);
                                PublicClass.WriteLog(data.PalletNo + "," + data.ChannelNoList[j] + "UploadMes调用失败");
                            }
                        }
                    }
                }
            }
            return bRet;
        }
        /// <summary>
        /// 上传数据到MES
        /// </summary>
        /// <param name="nDataType">上位机定义的数据类型 0化成 1分容 2DCIR 3校准工装 4 计量工装 5线序工装 6负压工装</param>
        /// <param name="datalist">要上传的数据列表</param>
        /// <returns></returns>
        public static bool UploadData(int nDataType, List<object> datalist, int isAuto)//nDataType老版0化成1分容2DCIR，新版（目前只有DCIR使用新版）这3种类型都是0，使用PublicClass.projectConfig.system.DeviceType代替老版判断
        {
            string PalletNo = "";
            string BatteryNo = "";
            string sOperation = "";
            List<string> Battcodes = new List<string>();
            List<int> sResult = new List<int>();
            List<string> sData = new List<string>();

            if (isAuto == 1) //手动直接提交 MES，返回。
            {
                return UploadMes(PublicClass.projectConfig.system.DeviceType, datalist);        
            }
            //if (nDataType == 0 || nDataType == 1)//化成、分容
            if (PublicClass.projectConfig.system.DeviceType == 0 || PublicClass.projectConfig.system.DeviceType == 1)//0化成1分容
            {
                try
                {
                    if (datalist != null && datalist.Count > 0)
                    {
                        for (int i = 0; i < datalist.Count; i++)
                        {
                            if (datalist[i] is TestDataClass)
                            {
                                TestDataClass data = (TestDataClass)datalist[i];//全部数据
                                List<string> nglist = GetNGBatteryNo(data);//NG数据
                                PalletNo = data.PalletNo;
                                foreach (string item in data.BatteryNoList)
                                {
                                    if (nglist.Contains(item) && item != "")
                                    {
                                        Battcodes.Add(item);
                                        sResult.Add(2);//ng2 ok1 无电芯0 未传默认值-2
                                        sData.Add("");
                                    }
                                    else if (!nglist.Contains(item) && item != "")
                                    {
                                        Battcodes.Add(item);
                                        sResult.Add(1);
                                        sData.Add("");
                                    }
                                    else if (item == "")
                                    {
                                        Battcodes.Add(item);
                                        sResult.Add(0);
                                        sData.Add("");
                                    }
                                }
                                PalletSrv.ctTrayDataRsp palletdata = CallWCSClass.GetTrayInfo(data.PalletNo);
                                if (palletdata != null && palletdata.data.test_status == 50)
                                {
                                    sOperation = "FORMN";
                                }
                                else if (palletdata != null && palletdata.data.test_status == 60)
                                {
                                    sOperation = "CAPAC1";
                                }
                                else if (palletdata != null && palletdata.data.test_status == 61)
                                {
                                    sOperation = "CAPAC6";
                                }
                                PalletSrv.MsgRsp result = CallWCSClass.SetFormAGBDGDCIRTestResult(sOperation, Battcodes.ToArray(), sResult.ToArray(), sData.ToArray());//处理具体上传的逻辑，NG数据上传
                                if (result != null && result.result)
                                {
                                    bool b = data.UpdateDataState("upload");//数据库中更新状态，表明已上传
                                    if (b)
                                    {
                                        PublicClass.WriteLog(PalletNo + "数据上传");
                                        PublicClass.WriteLog2DB(PalletNo + "UploadData调用成功", PublicClass.LogContentType.Dispatcher);
                                        PublicClass.WriteLog(PalletNo + "UploadData调用成功");
                                        UploadMes(PublicClass.projectConfig.system.DeviceType, datalist);
                                        return true;
                                    }
                                }
                                else
                                {
                                    PublicClass.WriteLog2DB(PalletNo + "UploadData调用失败", PublicClass.LogContentType.Dispatcher);
                                    PublicClass.WriteLog(PalletNo + "UploadData调用失败");
                                    return false;
                                }
                            }
                        }
                    }
                    /*                    PublicClass.WriteLog2DB(PalletNo + "UploadData调用失败：不满足datalist != null && datalist.Count > 0", PublicClass.LogContentType.Dispatcher);
                                        PublicClass.WriteLog(PalletNo + "UploadData调用失败：不满足datalist != null && datalist.Count > 0");*/
                    return false;
                }
                catch (Exception e)
                {
                    PublicClass.WriteLog2DB(PalletNo + "UploadData调用失败：" + e.Message, PublicClass.LogContentType.Dispatcher);
                    PublicClass.WriteLog(PalletNo + "UploadData调用失败：" + e.Message);
                }
            }
            //else if (nDataType == 2)//DCIR
            else if (PublicClass.projectConfig.system.DeviceType == 2)//2DCIR
            {
                try
                {
                    CallWCSClass.InitPalletSrv();
                    CallWCSClass.InitWarehouseSrv();
                    if (datalist != null && datalist.Count > 0)
                    {
                        for (int i = 0; i < datalist.Count; i++)
                        {
                            if (datalist[i] is DCIRTestResultClass && datalist[i] != null)
                            {
                                DCIRTestResultClass data = (DCIRTestResultClass)datalist[i];
                                if (data.BatteryNo != "")
                                {
                                    PalletNo = data.PalletNo;
                                    BatteryNo = data.BatteryNo;
                                    bool ngcheck = CheckDCIR(data);//判断是否NG
                                    if (!ngcheck)
                                    {
                                        Battcodes.Add(data.BatteryNo);
                                        sResult.Add(2);
                                        sData.Add("");
                                    }
                                    else if (ngcheck)
                                    {
                                        Battcodes.Add(data.BatteryNo);
                                        sResult.Add(1);
                                        sData.Add("");
                                    }
                                }
                                else if (data.BatteryNo == "")
                                {
                                    Battcodes.Add(data.BatteryNo);
                                    sResult.Add(0);
                                    sData.Add("");
                                }
                            }
                            else if (datalist[i] is TestDataClass && datalist[i] != null)
                            {
                                UploadMes(PublicClass.projectConfig.system.DeviceType, datalist);
                                return true;
                            }
                        }
                        sOperation = "TSDCIR";
                        PalletSrv.MsgRsp result = CallWCSClass.SetFormAGBDGDCIRTestResult(sOperation, Battcodes.ToArray(), sResult.ToArray(), sData.ToArray());
                        if (result != null && result.result)
                        {
                            //CallWCSClass.SetTrayStatus(PalletNo, "CAPAC6");
                            Dictionary<int, string> dic = GetBatteryNo(PalletNo);
                            string lastNotNullBattcode = "";
                            for (int i = 1; i <= dic.Count; i++)
                            {
                                if (dic.ElementAt(dic.Count - i).Value != "")
                                {
                                    lastNotNullBattcode = dic.ElementAt(dic.Count - i).Value;
                                    break;
                                }
                            }
                            if (Battcodes[0] == lastNotNullBattcode && Battcodes[0] != "")//如果是最后一个非空电池条码，则调用托盘状态跳转至CAPAC6
                            {
                                CallWCSClass.SetTrayStatus(PalletNo, "CAPAC6");
                            }
                            PublicClass.WriteLog2DB(BatteryNo + "UploadData调用成功", PublicClass.LogContentType.Dispatcher);
                            PublicClass.WriteLog(BatteryNo + "UploadData调用成功");
                            return true;  
                        }
                        else
                        {
                            PublicClass.WriteLog2DB(BatteryNo + "UploadData调用失败", PublicClass.LogContentType.Dispatcher);
                            PublicClass.WriteLog(BatteryNo + "UploadData调用失败");
                            return false;
                        }
                    }
                    PublicClass.WriteLog2DB(BatteryNo + "UploadData调用失败：不满足datalist != null && datalist.Count > 0", PublicClass.LogContentType.Dispatcher);
                    PublicClass.WriteLog(BatteryNo + "UploadData调用失败：不满足datalist != null && datalist.Count > 0");
                    return false;
                }
                catch (Exception e)
                {
                    PublicClass.WriteLog2DB(BatteryNo + "UploadData调用失败：" + e.Message, PublicClass.LogContentType.Dispatcher);
                    PublicClass.WriteLog(BatteryNo + "UploadData调用失败：" + e.Message);
                }
            }
            else if (nDataType == 3 || nDataType == 4)//校准工装、计量工装
            {
                if (datalist != null && datalist.Count > 0)
                {
                    for (int i = 0; i < datalist.Count; i++)
                    {
                        if (datalist[i] is CalibrationIndexClass)
                        {
                            CalibrationIndexClass data = (CalibrationIndexClass)datalist[i];
                            List<CalibrationValueClass> detailList = data.ToCaliList_NoUI();
                            //处理具体上传的逻辑
                            bool b = data.UpdateDataState("upload");//数据库中更新状态，表明已上传
                            if (b)
                                PublicClass.WriteLog(data.DeviceNo + "数据上传");
                        }
                    }
                }
                return true;
            }
            else if (nDataType == 5)//线序工装
            {
                if (datalist != null && datalist.Count > 0)
                {
                    for (int i = 0; i < datalist.Count; i++)
                    {
                        if (datalist[i] is WireOrderTestResultClass)
                        {
                            WireOrderTestResultClass data = (WireOrderTestResultClass)datalist[i];
                            //处理具体上传的逻辑
                            bool b = data.UpdateDataState("upload");//数据库中更新状态，表明已上传
                            if (b)
                                PublicClass.WriteLog(data.DeviceNo + "数据上传");
                        }
                    }
                }
                return true;
            }
            else if (nDataType == 6)//负压工装
            {
                if (datalist != null && datalist.Count > 0)
                {
                    for (int i = 0; i < datalist.Count; i++)
                    {
                        if (datalist[i] is CaliFuYaIndexClass)
                        {
                            CaliFuYaIndexClass data = (CaliFuYaIndexClass)datalist[i];
                            //处理具体上传的逻辑
                            bool b = data.UpdateDataState("upload");//数据库中更新状态，表明已上传
                            if (b)
                                PublicClass.WriteLog(data.DeviceNo + "数据上传");
                        }
                    }
                }
                return true;
            }

            return false;
        }

        #region 预约库位

        /// <summary>
        /// 预约库位类型
        /// </summary>
        /// <param name="id"></param>
        /// <param name="nPalletType"></param>
        /// <returns></returns>
        public static bool OrderPallet(DeviceClass device, int nPalletType)
        {
            if (OrderPalletCheck(device))
            {
                if (PublicClass.ShowMsgBox_Thread(PublicClass.GetLanguage("是否预约#").Replace("#", DeviceClass.PalletType2Name(nPalletType))) == 1)
                {
                    int id = PublicClass.ToInt(device.WarehouseNo);
                    int JS_PalletType = JSPalletType(nPalletType);//精实那边定义的托盘状态

                    WarehouseSrv.MsgRsp data = CallWCSClass.UpdateFormGetPutType(id, JS_PalletType);
                    if (data == null)
                        PublicClass.ShowTip("无法调用接口");
                    else
                    {
                        if (data.result)//调用成功
                        {
                            PublicClass.ShowTip("已预约", false);
                            return true;
                        }
                        else
                            PublicClass.ShowTip(data.msg);
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 把上位机的托盘类型转为精实那边的托盘类型
        /// </summary>
        /// <param name="nPalletType"></param>
        /// <returns></returns>
        private static int JSPalletType(int nPalletType)
        {
            int DCDCType = PublicClass.projectConfig.system.DCDCType;//0并联 1串联
            if (nPalletType == -1)//取消所有工装预约（送电池托盘）
                return 9;//9表示要正常料，70-89表示对应的工装
            else if (nPalletType == 1 || nPalletType == 2)//校准工装&计量工装&DCIR工装
            {
                if (DCDCType == 0) return 78;//并联精度工装
                if (DCDCType == 1) return 70;//串联精度工装
            }
            else if (nPalletType == 3)//线序工装
                return 79;
            else if (nPalletType == 4)//负压工装
                return 73;
            else if (nPalletType == 5)//拔吸嘴工装
                return 76;
            else if (nPalletType == 6)//插吸嘴工装
                return 75;
            else if (nPalletType == 7)//温度工装
                return 71;

            return 2;
        }

        private static bool OrderPalletCheck(DeviceClass device)
        {
            if (!PublicClass.HasPermission("设备控制"))
                return false;

            if (!device.IsOperationEnable(true))
                return false;


            return true;
        }

        #endregion

        #region 异常换库、NG排出

        /// <summary>
        /// 异常库位更换，注意不是换托盘，是库位出现了异常，换库位
        /// id表示对应库位的ID，涉及到因各种设备原因导致无法启动流程的库位
        /// 比如测堵、测漏失败
        /// </summary>
        /// <param name="id"></param>
        public static bool ErrWarehouseChange(DeviceClass device)
        {
            if (ErrTakeCheck(device))
            {
                if (PublicClass.ShowMsgBox_Thread("是否对当前托盘进行换库") == 1)
                {
                    int id = PublicClass.ToInt(device.WarehouseNo);
                    WarehouseSrv.MsgRsp data = CallWCSClass.UpdateErrTrayChangePlaces(id);
                    if (data == null)
                        PublicClass.ShowTip("无法调用接口");
                    else
                    {
                        if (data.result)//调用成功
                        {
                            PublicClass.ShowTip("已预约", false);
                            return true;
                        }
                        else
                            PublicClass.ShowTip(data.msg);
                    }
                }

            }

            return false;
        }

        /// <summary>
        /// NG排出
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool ErrPalletTake(DeviceClass device)
        {
            if (ErrTakeCheck(device))
            {
                if (PublicClass.ShowMsgBox_Thread("是否对当前托盘进行排出") == 1)
                {
                    int id = PublicClass.ToInt(device.WarehouseNo);
                    WarehouseSrv.MsgRsp data = CallWCSClass.UpdateErrTrayDischarge(id);
                    if (data == null)
                        PublicClass.ShowTip("无法调用接口");
                    else
                    {
                        if (data.result)//调用成功
                        {
                            PublicClass.ShowTip("已预约", false);
                            return true;
                        }
                        else
                            PublicClass.ShowTip(data.msg);
                    }
                }

            }

            return false;
        }


        /// <summary>
        /// 异常或NG的时候 要拿走托盘
        /// </summary>
        /// <returns></returns>
        private static bool ErrTakeCheck(DeviceClass device)
        {
            if (!PublicClass.HasPermission("设备控制"))
                return false;

            if (!device.IsOperationEnable(true))
                return false;

            if (device.IsTesting())
            {
                PublicClass.ShowTip("当前设备正在进行测试");
                return false;
            }

            if (device.dilist[PT.HasPallet_DIIndex] == "0")
            {
                PublicClass.ShowTip("当前库位没有托盘");
                return false;
            }

            if (device.dilist[PT.TK_DIIndex] == "0")
            {
                PublicClass.ShowTip("当前库位没有弹开到位");
                return false;
            }

            return true;
        }

        #endregion

        #region 启用/锁定

        public static bool SetWarehouseEnable(DeviceClass device, int nValue)
        {
            int id = PublicClass.ToInt(device.WarehouseNo);
            WarehouseSrv.MsgRsp data = CallWCSClass.UpdateManualAuto(id, nValue);

            if (data == null)
                PublicClass.ShowTip("无法调用接口");
            else
            {
                if (data.result)//调用成功
                {
                    return true;
                }
                else
                    PublicClass.ShowTip(data.msg);
            }

            return false;
        }

        #endregion
    }
}
